<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>学生信息分析平台 (SPA)</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
  <style>
    body { display: flex; flex-direction: column; min-height: 100vh; padding-top: 56px; }
    .view { display: none; width: 100%; }
    #app-container { flex: 1; padding-bottom: 20px; }
    .footer { background-color: #f8f9fa; padding: 1rem 0; text-align: center; margin-top: auto; }
    .card-title-sm { font-size: 1.1rem; }
    .loading-indicator { display: none; text-align: center; padding: 20px; font-size: 1.2em; }
    .list-group-item-action { cursor: pointer; }
    #topStudentsChart { min-height: 250px; }
  </style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary fixed-top">
  <div class="container-fluid">
    <a class="navbar-brand" href="#" id="brand-link">学生信息平台 (SPA)</a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarNav">
      <ul class="navbar-nav ms-auto">
        <li class="nav-item" id="nav-username-item" style="display:none;">
          <span class="navbar-text me-3"><span id="nav-username"></span></span>
        </li>
        <li class="nav-item" id="nav-logout-item" style="display:none;">
          <button class="btn btn-outline-light btn-sm" id="logoutButton">退出登录</button>
        </li>
        <li class="nav-item" id="nav-login-item">
          <a class="nav-link" href="#" id="loginViewLink">登录</a>
        </li>
        <li class="nav-item" id="nav-register-item">
          <a class="nav-link" href="#" id="registerViewLink">注册</a>
        </li>
      </ul>
    </div>
  </div>
</nav>

<div id="app-container" class="container mt-4">
  <div id="login-view" class="view">
    <div class="row justify-content-center">
      <div class="col-md-6 col-lg-4">
        <div class="card shadow-sm mt-4">
          <div class="card-header bg-primary text-white"><h3 class="mb-0 text-center">用户登录</h3></div>
          <div class="card-body">
            <form id="loginForm">
              <div id="login-error" class="alert alert-danger mt-2" style="display:none;"></div>
              <div class="mb-3">
                <label for="loginUsername" class="form-label">用户名</label>
                <input type="text" class="form-control" id="loginUsername" name="username" required>
              </div>
              <div class="mb-3">
                <label for="loginPassword" class="form-label">密码</label>
                <input type="password" class="form-control" id="loginPassword" name="password" required>
              </div>
              <div class="d-grid">
                <button type="submit" class="btn btn-primary">登录</button>
              </div>
            </form>
          </div>
          <div class="card-footer text-center">
            <small>还没有账户? <a href="#" id="loginToRegisterLink">立即注册</a></small>
          </div>
        </div>
      </div>
    </div>
  </div>

  <div id="register-view" class="view">
    <div class="row justify-content-center">
      <div class="col-md-6 col-lg-5">
        <div class="card shadow-sm mt-4">
          <div class="card-header bg-success text-white"><h3 class="mb-0 text-center">创建账户</h3></div>
          <div class="card-body">
            <form id="registerForm">
              <div id="register-error" class="alert alert-danger mt-2" style="display:none;"></div>
              <div id="register-success" class="alert alert-success mt-2" style="display:none;"></div>
              <div class="mb-3">
                <label for="registerUsername" class="form-label">用户名</label>
                <input type="text" class="form-control" id="registerUsername" name="username" required>
              </div>
              <div class="mb-3">
                <label for="registerEmail" class="form-label">邮箱 (可选)</label>
                <input type="email" class="form-control" id="registerEmail" name="email">
              </div>
              <div class="mb-3">
                <label for="registerPassword" class="form-label">密码 (至少6位)</label>
                <input type="password" class="form-control" id="registerPassword" name="password" required minlength="6">
              </div>
              <div class="mb-3">
                <label for="registerConfirmPassword" class="form-label">确认密码</label>
                <input type="password" class="form-control" id="registerConfirmPassword" name="confirm_password" required minlength="6">
              </div>
              <div class="d-grid">
                <button type="submit" class="btn btn-success">注册</button>
              </div>
            </form>
          </div>
          <div class="card-footer text-center">
            <small>已有账户? <a href="#" id="registerToLoginLink">直接登录</a></small>
          </div>
        </div>
      </div>
    </div>
  </div>

  <div id="dashboard-view" class="view">
    <h2 class="mb-4">学生数据仪表盘 <span id="dashboard-username" class="fs-5 text-muted"></span></h2>
    <div id="dashboard-loading" class="loading-indicator alert alert-info">加载数据中... </div>
    <div id="dashboard-content" style="display:none;">
      <div class="row mb-4">
        <div class="col-md-7">
          <div class="card shadow-sm">
            <div class="card-header bg-info text-white">
              <h5 class="card-title-sm mb-0">为您推荐的 Top 6 学生</h5>
              <small>(基于学号: <span id="cf-target-student-id"></span>)</small>
            </div>
            <div id="cfRecommendationsList" class="list-group list-group-flush">
            </div>
          </div>
        </div>
        <div class="col-md-5">
          <div class="card shadow-sm">
            <div class="card-header bg-warning text-dark">
              <h5 class="card-title-sm mb-0">全局绩点 Top 3 学生</h5>
            </div>
            <div id="topStudentsList" class="list-group list-group-flush">
            </div>
            <div class="card-body">
              <div id="topStudentsChart" style="width: 100%; height:250px;"></div>
            </div>
          </div>
        </div>
      </div>

      <div class="card shadow-sm mb-4">
        <div class="card-header"><h5 class="card-title-sm mb-0">搜索学生信息</h5></div>
        <div class="card-body">
          <div class="input-group">
            <input type="text" id="dashboardSearchInput" class="form-control form-control-lg" placeholder="输入学号或姓名进行搜索...">
            <button class="btn btn-outline-primary btn-lg" type="button" id="dashboardSearchButton">搜索</button>
          </div>
          <div id="dashboardSearchResults" class="mt-3 list-group"></div>
        </div>
      </div>

      <div class="row">
        <div class="col-md-6 mb-4">
          <div class="card shadow-sm">
            <div class="card-header"><h5 class="card-title-sm mb-0">学生详细信息</h5></div>
            <div class="card-body" id="dashboardStudentDetailPanel"><p class="text-muted">点击学生查看详情。</p></div>
          </div>
        </div>
        <div class="col-md-6 mb-4">
          <div class="card shadow-sm">
            <div class="card-header"><h5 class="card-title-sm mb-0">与选中学生相似的 Top 3 学生</h5></div>
            <div class="list-group list-group-flush" id="dashboardSimilarStudentsPanel"><div class="list-group-item text-muted">选择学生查看相似推荐。</div></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
<footer class="footer">
  <div class="container">
    <span class="text-muted">&copy; <span id="currentYear"></span> 学生数据分析平台. (当前时间: <span id="currentTime"></span>)</span>
  </div>
</footer>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.5.0/dist/echarts.min.js"></script>

<script>
  let currentViewId = 'login-view';
  const API_BASE_URL = 'http://localhost:5000';
  const DEFAULT_STUDENT_ID_FOR_CF = '';

  const views = { login: document.getElementById('login-view'), register: document.getElementById('register-view'), dashboard: document.getElementById('dashboard-view') };
  const navItems = { username: document.getElementById('nav-username-item'), logout: document.getElementById('nav-logout-item'), login: document.getElementById('nav-login-item'), register: document.getElementById('nav-register-item') };
  const navUsernameSpan = document.getElementById('nav-username');
  const brandLink = document.getElementById('brand-link');
  const loginViewLink = document.getElementById('loginViewLink');
  const registerViewLink = document.getElementById('registerViewLink');
  const loginToRegisterLink = document.getElementById('loginToRegisterLink');
  const registerToLoginLink = document.getElementById('registerToLoginLink');
  const logoutButton = document.getElementById('logoutButton');

  const cfTargetStudentIdSpan = document.getElementById('cf-target-student-id');
  const cfRecommendationsListDiv = document.getElementById('cfRecommendationsList');
  const topStudentsListDiv = document.getElementById('topStudentsList');
  const topStudentsChartDiv = document.getElementById('topStudentsChart');
  const dashboardSearchInput = document.getElementById('dashboardSearchInput');
  const dashboardSearchButton = document.getElementById('dashboardSearchButton');
  const dashboardSearchResultsDiv = document.getElementById('dashboardSearchResults');
  const dashboardStudentDetailPanel = document.getElementById('dashboardStudentDetailPanel');
  const dashboardSimilarStudentsPanel = document.getElementById('dashboardSimilarStudentsPanel');
  const dashboardLoadingDiv = document.getElementById('dashboard-loading');
  const dashboardContentDiv = document.getElementById('dashboard-content');
  const dashboardUsernameSpan = document.getElementById('dashboard-username');

  function sanitizeHTML(str) {
    const temp = document.createElement('div');
    if (str === null || str === undefined) return '';
    temp.textContent = String(str);
    return temp.innerHTML;
  }

  function displayMessage(elementId, message, isSuccess = false) {
    const msgDiv = document.getElementById(elementId);
    if (msgDiv) {
      msgDiv.textContent = message;
      msgDiv.className = `alert mt-2 ${isSuccess ? 'alert-success' : 'alert-danger'}`;
      msgDiv.style.display = 'block';
    }
  }

  function clearMessage(elementId) {
    const msgDiv = document.getElementById(elementId);
    if (msgDiv) msgDiv.style.display = 'none';
  }

  function showView(viewId, loadData = false) {
    currentViewId = viewId;
    Object.values(views).forEach(view => view.style.display = view.id === viewId ? 'block' : 'none');
    updateNavUI();
    if (viewId === 'dashboard-view' && loadData) loadDashboardData();
  }

  function updateNavUI() {
    const isLoggedIn = sessionStorage.getItem('isLoggedIn') === 'true';
    const username = sessionStorage.getItem('username');

    navItems.username.style.display = isLoggedIn ? 'list-item' : 'none';
    navItems.logout.style.display = isLoggedIn ? 'list-item' : 'none';
    navItems.login.style.display = isLoggedIn ? 'none' : 'list-item';
    navItems.register.style.display = isLoggedIn ? 'none' : 'list-item';

    navUsernameSpan.textContent = username || '用户';
    if (dashboardUsernameSpan) dashboardUsernameSpan.textContent = isLoggedIn ? `(欢迎, ${sanitizeHTML(username)})` : '';
  }

  async function fetchData(url, options = {}) {
    try {
      const response = await fetch(API_BASE_URL + url, options);
      if (!response.ok) {
        let errorMsg = `HTTP error! status: ${response.status}`;
        try { errorMsg = (await response.json()).error || errorMsg; } catch (e) {}
        throw new Error(errorMsg);
      }
      return await response.json();
    } catch (error) {
      console.error(`Fetch error for ${url}:`, error.message);
      throw error;
    }
  }

  document.getElementById('loginForm')?.addEventListener('submit', async function(e) {
    e.preventDefault();
    clearMessage('login-error');
    const formData = new FormData();
    formData.append('username', document.getElementById('loginUsername').value);
    formData.append('password', document.getElementById('loginPassword').value);

    try {
      const data = await fetchData('/login', { method: 'POST', body: formData });
      if (data.success) {
        sessionStorage.setItem('isLoggedIn', 'true');
        sessionStorage.setItem('username', data.username || formData.get('username'));
        sessionStorage.setItem('currentStudentIdForCF', formData.get('username'));
        showView('dashboard-view', true);
      } else {
        displayMessage('login-error', data.error || '登录失败');
      }
    } catch (error) {
      displayMessage('login-error', error.message || '登录请求失败');
    }
  });

  document.getElementById('registerForm')?.addEventListener('submit', async function(e) {
    e.preventDefault();
    clearMessage('register-error');
    clearMessage('register-success');

    const password = document.getElementById('registerPassword').value;
    if (password !== document.getElementById('registerConfirmPassword').value) {
      displayMessage('register-error', '两次输入的密码不一致！');
      return;
    }
    if (password.length < 6) {
      displayMessage('register-error', '密码长度至少为6位！');
      return;
    }

    const formData = new FormData();
    formData.append('username', document.getElementById('registerUsername').value);
    formData.append('password', password);
    const email = document.getElementById('registerEmail').value;
    if (email) formData.append('email', email);

    try {
      const data = await fetchData('/register', { method: 'POST', body: formData });
      if (data.success) {
        displayMessage('register-success', '注册成功！请登录。', true);
        this.reset();
        setTimeout(() => showView('login-view'), 2000);
      } else {
        displayMessage('register-error', data.error || '注册失败');
      }
    } catch (error) {
      displayMessage('register-error', error.message || '注册请求失败');
    }
  });

  async function logoutUser() {
    try { await fetchData('/logout', { method: 'POST' }); } catch (error) { console.warn("Logout API call failed"); }
    sessionStorage.removeItem('isLoggedIn');
    sessionStorage.removeItem('username');
    sessionStorage.removeItem('currentStudentIdForCF');
    showView('login-view');
  }

  async function checkAuthStatus() {
    try {
      const data = await fetchData('/api/auth_status');
      if (data.authenticated) {
        sessionStorage.setItem('isLoggedIn', 'true');
        sessionStorage.setItem('username', data.username);
        if (!sessionStorage.getItem('currentStudentIdForCF')) {
          sessionStorage.setItem('currentStudentIdForCF', data.username);
        }
        showView('dashboard-view', true);
      } else {
        sessionStorage.removeItem('isLoggedIn');
        sessionStorage.removeItem('username');
        sessionStorage.removeItem('currentStudentIdForCF');
        showView('login-view');
      }
    } catch (error) {
      sessionStorage.removeItem('isLoggedIn');
      sessionStorage.removeItem('username');
      sessionStorage.removeItem('currentStudentIdForCF');
      showView('login-view');
    }
  }

  let topStudentsEchartInstance = null;

  async function loadDashboardData() {
    if (sessionStorage.getItem('isLoggedIn') !== 'true') {
      showView('login-view');
      return;
    }

    dashboardLoadingDiv.style.display = 'block';
    dashboardContentDiv.style.display = 'none';
    cfRecommendationsListDiv.innerHTML = '<div class="list-group-item">加载中...</div>';
    topStudentsListDiv.innerHTML = '<div class="list-group-item">加载中...</div>';
    dashboardSearchResultsDiv.innerHTML = '';
    dashboardStudentDetailPanel.innerHTML = '<p class="text-muted">点击学生查看详情。</p>';
    dashboardSimilarStudentsPanel.innerHTML = '<div class="list-group-item text-muted">选择学生查看相似推荐。</div>';

    try {
      const studentIdForCF = sessionStorage.getItem('currentStudentIdForCF') || sessionStorage.getItem('username') || DEFAULT_STUDENT_ID_FOR_CF;
      cfTargetStudentIdSpan.textContent = sanitizeHTML(studentIdForCF);

      const [cfData, topStudentsData] = await Promise.all([
        fetchData(`/api/students/similar/${encodeURIComponent(studentIdForCF)}`),
        fetchData('/api/students/top')
      ]);

      renderCfRecommendations(cfData);
      renderTopStudents(topStudentsData);
      renderTopStudentsChart(topStudentsData);

    } catch (error) {
      cfRecommendationsListDiv.innerHTML = `<div class="list-group-item text-danger">无法加载推荐数据: ${sanitizeHTML(error.message)}</div>`;
      topStudentsListDiv.innerHTML = `<div class="list-group-item text-danger">无法加载Top学生数据: ${sanitizeHTML(error.message)}</div>`;
      if (topStudentsEchartInstance) { topStudentsEchartInstance.dispose(); topStudentsEchartInstance = null; }
      if (topStudentsChartDiv) topStudentsChartDiv.innerHTML = '<p class="text-danger text-center">图表数据加载失败。</p>';
    } finally {
      dashboardLoadingDiv.style.display = 'none';
      dashboardContentDiv.style.display = 'block';
    }
  }

  function renderCfRecommendations(recs) {
    cfRecommendationsListDiv.innerHTML = '';
    if (!recs || recs.error) {
      cfRecommendationsListDiv.innerHTML = `<div class="list-group-item text-danger">${recs?.error || '暂无个性化推荐'}</div>`;
      return;
    }
    recs.forEach(rec => {
      const item = document.createElement('a');
      item.href = '#';
      item.className = 'list-group-item list-group-item-action d-flex justify-content-between align-items-center student-link';
      item.dataset.studentId = rec.recommended_student_id;
      item.innerHTML = `
        <span>${sanitizeHTML(rec.name)} (学号: ${sanitizeHTML(rec.recommended_student_id)}) - GPA: ${rec.latest_gpa ? Number(rec.latest_gpa).toFixed(2) : 'N/A'}</span>
        <span class="badge bg-primary rounded-pill">相似度: ${Number(rec.score).toFixed(2)}</span>`;
      cfRecommendationsListDiv.appendChild(item);
    });
  }

  function renderTopStudents(students) {
    topStudentsListDiv.innerHTML = '';
    if (!students || students.error) {
      topStudentsListDiv.innerHTML = `<div class="list-group-item text-danger">${students?.error || '暂无Top学生数据'}</div>`;
      return;
    }
    students.forEach(student => {
      const item = document.createElement('a');
      item.href = '#';
      item.className = 'list-group-item list-group-item-action d-flex justify-content-between align-items-center student-link';
      item.dataset.studentId = student.student_id;
      item.innerHTML = `
        <span><span class="badge bg-dark me-2">#${sanitizeHTML(student.rank)}</span> ${sanitizeHTML(student.name)} (学号: ${sanitizeHTML(student.student_id)})</span>
        <span class="badge bg-success rounded-pill">GPA: ${Number(student.latest_gpa).toFixed(2)}</span>`;
      topStudentsListDiv.appendChild(item);
    });
  }

  function renderTopStudentsChart(students) {
    if (!topStudentsChartDiv) return;
    if (!students || students.error || !students.length) {
      topStudentsChartDiv.innerHTML = '<p class="text-muted text-center p-3">无数据显示图表</p>';
      if (topStudentsEchartInstance) { try { topStudentsEchartInstance.dispose(); } catch(e) {} }
      return;
    }

    if (topStudentsEchartInstance) { try { topStudentsEchartInstance.dispose(); } catch(e) {} }
    try {
      topStudentsEchartInstance = echarts.init(topStudentsChartDiv);
      topStudentsEchartInstance.setOption({
        title: { text: 'Top 学生绩点', left: 'center', textStyle: {fontSize: 16}},
        tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
        grid: { left: '10%', right: '10%', bottom: '15%', containLabel: true },
        xAxis: { type: 'category', data: students.map(s => s.name), axisLabel: { interval: 0, rotate: 30, fontSize: 10 } },
        yAxis: { type: 'value', name: '绩点 (GPA)', min: 0, max: 10 },
        series: [{
          name: 'GPA',
          type: 'bar',
          data: students.map(s => Number(s.latest_gpa).toFixed(2)),
          itemStyle: { color: '#5470C6' },
          barWidth: '60%',
          label: { show: true, position: 'top' }
        }]
      });
    } catch (e) {
      topStudentsChartDiv.innerHTML = "<p class='text-danger text-center p-3'>图表加载失败。</p>";
    }
  }

  window.addEventListener('resize', () => topStudentsEchartInstance?.resize());

  dashboardSearchButton?.addEventListener('click', performDashboardSearch);
  dashboardSearchInput?.addEventListener('keypress', (e) => { if (e.key === 'Enter') performDashboardSearch(); });

  async function performDashboardSearch() {
    const query = dashboardSearchInput.value.trim();
    if (query.length < 1) {
      dashboardSearchResultsDiv.innerHTML = '<div class="list-group-item text-warning">请输入至少1个字符进行搜索。</div>';
      return;
    }

    dashboardSearchResultsDiv.innerHTML = '<div class="list-group-item text-info">正在搜索</div>';
    try {
      const data = await fetchData(`/api/students/search?q=${encodeURIComponent(query)}`);
      renderDashboardSearchResults(data);
    } catch (error) {
      dashboardSearchResultsDiv.innerHTML = `<div class="list-group-item text-danger">搜索失败: ${sanitizeHTML(error.message)}</div>`;
    }
  }

  function renderDashboardSearchResults(students) {
    dashboardSearchResultsDiv.innerHTML = '';
    if (!students || students.error) {
      dashboardSearchResultsDiv.innerHTML = `<div class="list-group-item text-danger">${students?.error || '未找到匹配的学生'}</div>`;
      return;
    }
    students.forEach(student => {
      const item = document.createElement('a');
      item.href = '#';
      item.className = 'list-group-item list-group-item-action student-link';
      item.dataset.studentId = student.student_id;
      item.innerHTML = `<strong>${sanitizeHTML(student.name)}</strong> (学号: ${sanitizeHTML(student.student_id)}) - 班级: ${sanitizeHTML(student.class_id || 'N/A')}, GPA: ${student.latest_gpa ? Number(student.latest_gpa).toFixed(2) : 'N/A'}`;
      dashboardSearchResultsDiv.appendChild(item);
    });
  }

  async function loadStudentAllInfo(studentId, updateCfRecommendations = true) {
    sessionStorage.setItem('currentStudentIdForCF', studentId);
    cfTargetStudentIdSpan.textContent = sanitizeHTML(studentId);

    dashboardStudentDetailPanel.innerHTML = '<p class="text-info">正在加载学生详细信息</p>';
    dashboardSimilarStudentsPanel.innerHTML = '<div class="list-group-item text-info">正在加载相似学生推荐</div>';

    const promises = [
      loadDashboardStudentDetail(studentId),
      loadDashboardSimilarStudents(studentId)
    ];

    if (updateCfRecommendations) {
      promises.push(fetchData(`/api/students/similar/${encodeURIComponent(studentId)}`).then(renderCfRecommendations));
    }

    await Promise.allSettled(promises).then(results => {
      results.forEach((result, index) => {
        if (result.status === 'rejected') {
          const errorMsgs = ['加载学生详情失败', '加载相似学生推荐失败', '无法加载新的推荐数据'];
          if (index === 0) dashboardStudentDetailPanel.innerHTML = `<p class="text-danger">${errorMsgs[index]}: ${sanitizeHTML(result.reason.message)}</p>`;
          if (index === 1 && dashboardSimilarStudentsPanel) dashboardSimilarStudentsPanel.innerHTML = `<div class="list-group-item text-danger">${errorMsgs[index]}: ${sanitizeHTML(result.reason.message)}</div>`;
          if (index === 2 && cfRecommendationsListDiv) cfRecommendationsListDiv.innerHTML = `<div class="list-group-item text-danger">${errorMsgs[index]}: ${sanitizeHTML(result.reason.message)}</div>`;
        }
      });
    });
  }

  async function loadDashboardStudentDetail(studentId) {
    try {
      const data = await fetchData(`/api/students/info/${encodeURIComponent(studentId)}`);
      if (data.error) {
        dashboardStudentDetailPanel.innerHTML = `<p class="text-danger">${sanitizeHTML(data.error)}</p>`;
        return;
      }

      const genderText = data.gender === 1 ? '男' : (data.gender === 0 ? '女' : '未知');
      const statusText = data.status === 'A' ? '在校' : (data.status === 'L' ? '毕业' : '未知');
      const dobText = data.dob ? new Date(data.dob + 'T00:00:00Z').toLocaleDateString('zh-CN') : 'N/A';

      dashboardStudentDetailPanel.innerHTML = `
        <h5 class="card-title">${sanitizeHTML(data.name)} <small class="text-muted">(学号: ${sanitizeHTML(data.student_id)})</small></h5>
        <ul class="list-unstyled">
          <li><strong>班级号:</strong> ${sanitizeHTML(data.class_id || 'N/A')}</li>
          <li><strong>性别:</strong> ${sanitizeHTML(genderText)}</li>
          <li><strong>出生日期:</strong> ${sanitizeHTML(dobText)}</li>
          <li><strong>最新学期:</strong> ${sanitizeHTML(data.latest_semester || 'N/A')}</li>
          <li><strong>最新绩点:</strong> ${data.latest_gpa ? Number(data.latest_gpa).toFixed(2) : 'N/A'}</li>
          <li><strong>在校状态:</strong> ${sanitizeHTML(statusText)}</li>
        </ul>`;
    } catch (error) {
      dashboardStudentDetailPanel.innerHTML = `<p class="text-danger">加载学生详情失败: ${sanitizeHTML(error.message)}</p>`;
      throw error;
    }
  }

  async function loadDashboardSimilarStudents(studentId) {
    try {
      const data = await fetchData(`/api/students/similar/${encodeURIComponent(studentId)}`);
      dashboardSimilarStudentsPanel.innerHTML = '';
      if (data.error) {
        dashboardSimilarStudentsPanel.innerHTML = `<div class="list-group-item text-danger">${sanitizeHTML(data.error)}</div>`;
        return;
      }

      const limitedData = data.slice(0, 3);
      if (!limitedData.length) {
        dashboardSimilarStudentsPanel.innerHTML = '<div class="list-group-item">未找到相似学生推荐。</div>';
        return;
      }

      limitedData.forEach(student => {
        const item = document.createElement('a');
        item.href = '#';
        item.className = 'list-group-item list-group-item-action d-flex justify-content-between align-items-center student-link';
        item.dataset.studentId = student.recommended_student_id;
        item.innerHTML = `
          <span>${sanitizeHTML(student.name)} (学号: ${sanitizeHTML(student.recommended_student_id)}) - GPA: ${student.latest_gpa ? Number(student.latest_gpa).toFixed(2) : 'N/A'}</span>
          <span class="badge bg-info rounded-pill">匹配分: ${Number(student.score).toFixed(2)}</span>`;
        dashboardSimilarStudentsPanel.appendChild(item);
      });
    } catch (error) {
      dashboardSimilarStudentsPanel.innerHTML = `<div class="list-group-item text-danger">加载相似学生推荐失败: ${sanitizeHTML(error.message)}</div>`;
      throw error;
    }
  }

  function updateFooterTime() {
    const now = new Date();
    const yearSpan = document.getElementById('currentYear');
    const timeSpan = document.getElementById('currentTime');
    if (yearSpan) yearSpan.textContent = now.getFullYear();
    if (timeSpan) timeSpan.textContent = now.toLocaleString('zh-CN', { hour12: false });
  }

  document.addEventListener('DOMContentLoaded', function() {
    updateFooterTime();
    setInterval(updateFooterTime, 60000);
    checkAuthStatus();

    brandLink.addEventListener('click', (e) => { e.preventDefault(); showView(sessionStorage.getItem('isLoggedIn') === 'true' ? 'dashboard-view' : 'login-view', true); });
    loginViewLink.addEventListener('click', (e) => { e.preventDefault(); showView('login-view'); });
    registerViewLink.addEventListener('click', (e) => { e.preventDefault(); showView('register-view'); });
    loginToRegisterLink.addEventListener('click', (e) => { e.preventDefault(); showView('register-view'); });
    registerToLoginLink.addEventListener('click', (e) => { e.preventDefault(); showView('login-view'); });
    logoutButton.addEventListener('click', (e) => { e.preventDefault(); logoutUser(); });

    document.body.addEventListener('click', (e) => {
      const studentLink = e.target.closest('.student-link');
      if (studentLink) {
        e.preventDefault();
        const studentId = studentLink.dataset.studentId;
        const isSearchResult = studentLink.closest('#dashboardSearchResults') !== null;
        isSearchResult ? Promise.all([loadDashboardStudentDetail(studentId), loadDashboardSimilarStudents(studentId)]) : loadStudentAllInfo(studentId);
      }
    });
  });
</script>
</body>
</html>